package com.smartcampusbackend.controller;

import com.smartcampusbackend.model.AcademicWarning;
import com.smartcampusbackend.model.MakeupExamApplication;
import com.smartcampusbackend.service.AcademicWarningService;
import com.smartcampusbackend.service.MakeupExamApplicationService;
import com.smartcampusbackend.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.smartcampusbackend.model.Grade;
import com.smartcampusbackend.model.Course;
import com.smartcampusbackend.model.User;
import com.smartcampusbackend.mapper.GradeMapper;
import com.smartcampusbackend.mapper.CourseMapper;
import com.smartcampusbackend.mapper.UserMapper;
import com.smartcampusbackend.mapper.AcademicWarningMapper;

@RestController
@RequestMapping("/api")
public class AcademicWarningController {
    private static final Logger logger = LoggerFactory.getLogger(AcademicWarningController.class);
    
    @Autowired
    private AcademicWarningService academicWarningService;

    @Autowired
    private MakeupExamApplicationService makeupExamApplicationService;

    @Autowired
    private UserService userService;

    @Autowired
    private GradeMapper gradeMapper;

    @Autowired
    private CourseMapper courseMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private AcademicWarningMapper academicWarningMapper;

    // 学生查看自己的学业预警
    @GetMapping("/users/me/academic-warnings")
    public List<Map<String, Object>> getStudentAcademicWarnings(@RequestParam String studentId) {
        logger.info("学生查询学业预警，studentId: {}", studentId);
        
        // 尝试转换为Long类型
        Long studentIdLong;
        try {
            studentIdLong = Long.valueOf(studentId);
        } catch (NumberFormatException e) {
            // 如果无法转换，则使用原始字符串ID
            studentIdLong = null;
        }
        
        // 查询学业预警
        List<AcademicWarning> warnings;
        if (studentIdLong != null) {
            warnings = academicWarningService.listStudentWarnings(studentIdLong);
        } else {
            // 尝试使用字符串ID
            warnings = academicWarningService.listStudentWarningsStr(studentId);
        }
        
        logger.info("查询到学业预警数量: {}", warnings.size());
        
        // 获取该学生的补考申请状态
        List<MakeupExamApplication> applications = makeupExamApplicationService.getStudentApplications(studentId);
        
        // 课程ID到补考申请的映射
        Map<String, MakeupExamApplication> courseToApplicationMap = new HashMap<>();
        for (MakeupExamApplication app : applications) {
            courseToApplicationMap.put(app.getCourseId(), app);
        }
        
        // 将补考状态添加到预警信息中
        List<Map<String, Object>> enrichedWarnings = new ArrayList<>();
        for (AcademicWarning warning : warnings) {
            Map<String, Object> warningMap = new HashMap<>();
            warningMap.put("warningId", warning.getId());
            warningMap.put("studentId", warning.getStudentId());
            warningMap.put("courseId", warning.getCourseId());
            warningMap.put("courseName", warning.getCourseName());
            warningMap.put("teacherId", warning.getTeacherId());
            warningMap.put("teacherName", warning.getTeacherName());
            warningMap.put("semester", warning.getSemester());
            warningMap.put("courseCredit", warning.getCourseCredit());
            warningMap.put("warningDate", warning.getWarningDate());
            warningMap.put("createTime", warning.getCreateTime());
            warningMap.put("updateTime", warning.getUpdateTime());
            warningMap.put("description", warning.getDescription());
            warningMap.put("status", warning.getStatus());
            warningMap.put("warningType", warning.getWarningType());
            
            // 添加补考信息
            MakeupExamApplication application = courseToApplicationMap.get(warning.getCourseId());
            if (application != null) {
                warningMap.put("makeupStatus", application.getStatus());
                warningMap.put("makeupScore", application.getMakeupScore());
                warningMap.put("makeupApplyTime", application.getApplyTime());
                warningMap.put("makeupReviewTime", application.getReviewTime());
            } else {
                warningMap.put("makeupStatus", "未申请");
            }
            
            enrichedWarnings.add(warningMap);
        }
        
        return enrichedWarnings;
    }

    // 管理员查看所有学业预警
    @GetMapping("/admin/academic-warnings")
    public List<AcademicWarning> listAllWarnings() {
        return academicWarningService.listAdminWarnings(null);
    }
    
    // 教师查看自己课程的学业预警
    @GetMapping("/teacher/academic-warnings")
    public List<AcademicWarning> listTeacherWarnings(@RequestParam String teacherId) {
        logger.info("教师查询学业预警，teacherId: {}", teacherId);
        List<AcademicWarning> warnings = academicWarningService.listTeacherWarnings(Long.valueOf(teacherId));
        logger.info("查询到学业预警数量: {}", warnings.size());
        return warnings;
    }
    
    // 教师查看课程学业预警统计
    @GetMapping("/teacher/academic-warnings/stats")
    public List<Map<String, Object>> getTeacherWarningStats(@RequestParam String teacherId) {
        logger.info("教师查看课程学业预警统计，teacherId: {}", teacherId);
        Long teacherIdLong = null;
        try {
            teacherIdLong = Long.valueOf(teacherId);
        } catch (NumberFormatException e) {
            // 如果无法转换，则使用原始字符串ID
            logger.warn("无法将教师ID转换为Long类型: {}", teacherId);
        }
        
        List<Map<String, Object>> stats;
        if (teacherIdLong != null) {
            stats = academicWarningService.getWarningStatsByTeacher(teacherIdLong);
        } else {
            // 这里应该有处理字符串ID的方法，暂时返回空列表
            stats = new ArrayList<>();
        }
        
        // 确保返回的数据包含所有需要的字段
        for (Map<String, Object> stat : stats) {
            if (!stat.containsKey("teacherName")) {
                stat.put("teacherName", "未知");
            }
            if (!stat.containsKey("semester")) {
                stat.put("semester", "未知");
            }
            if (!stat.containsKey("credits")) {
                stat.put("credits", 0.0);
            }
        }
        
        return stats;
    }
    
    // 获取管理员学业预警统计
    @GetMapping("/admin/academic-warnings/stats")
    public List<Map<String, Object>> getAllWarningStats() {
        logger.info("管理员查看学业预警统计");
        List<Map<String, Object>> stats = academicWarningService.getAllWarningStats();
        
        // 确保返回的数据包含所有需要的字段
        for (Map<String, Object> stat : stats) {
            if (!stat.containsKey("teacherName")) {
                stat.put("teacherName", "未知");
            }
            if (!stat.containsKey("semester")) {
                stat.put("semester", "未知");
            }
            if (!stat.containsKey("credits")) {
                stat.put("credits", 0.0);
            }
        }
        
        return stats;
    }
    
    // 根据课程ID获取学业预警学生列表
    @GetMapping("/academic-warnings/course/{courseId}")
    public List<Map<String, Object>> getWarningStudentsByCourse(@PathVariable String courseId) {
        logger.info("获取课程学业预警学生列表，courseId: {}", courseId);
        try {
            List<Map<String, Object>> students = academicWarningService.getWarningStudentsByCourse(courseId);
            logger.info("获取到课程 {} 的预警学生数量: {}", courseId, students.size());
            
            // 丰富学生信息
            for (Map<String, Object> student : students) {
                // 确保studentId是字符串类型
                Object studentIdObj = student.get("studentId");
                String studentId;
                if (studentIdObj instanceof Integer) {
                    studentId = String.valueOf(studentIdObj);
                    // 更新Map中的studentId为字符串类型
                    student.put("studentId", studentId);
                } else if (studentIdObj instanceof Long) {
                    studentId = String.valueOf(studentIdObj);
                    // 更新Map中的studentId为字符串类型
                    student.put("studentId", studentId);
                } else {
                    studentId = (String) studentIdObj;
                }
                
                List<MakeupExamApplication> applications = makeupExamApplicationService.getStudentApplications(studentId);
                
                for (MakeupExamApplication app : applications) {
                    if (app.getCourseId().equals(courseId)) {
                        student.put("makeupStatus", app.getStatus());
                        student.put("makeupScore", app.getMakeupScore());
                        student.put("makeupApplyTime", app.getApplyTime());
                        student.put("makeupReviewTime", app.getReviewTime());
                        break;
                    }
                }
                
                // 如果没有找到补考申请，设置默认值
                if (!student.containsKey("makeupStatus")) {
                    student.put("makeupStatus", "未申请");
                }
            }
            
            return students;
        } catch (Exception e) {
            logger.error("获取课程学业预警学生列表失败: courseId={}, error={}", courseId, e.getMessage(), e);
            return new ArrayList<>();
        }
    }
    
    // 生成学业预警（从不及格成绩生成）
    @PostMapping("/admin/academic-warnings/generate")
    public ResponseEntity<Map<String, Object>> generateWarnings() {
        logger.info("开始从不及格成绩生成学业预警");
        try {
            academicWarningService.generateWarningsFromGrades();
            Map<String, Object> response = new HashMap<>();
            response.put("success", true);
            response.put("message", "学业预警生成成功");
            logger.info("学业预警生成成功");
            return ResponseEntity.ok(response);
        } catch (Exception e) {
            logger.error("生成学业预警失败: {}", e.getMessage(), e);
            Map<String, Object> response = new HashMap<>();
            response.put("success", false);
            response.put("message", "学业预警生成失败: " + e.getMessage());
            return ResponseEntity.ok(response);
        }
    }
    
    // 更新学业预警状态
    @PutMapping("/academic-warnings/{warningId}/status")
    public Map<String, Object> updateWarningStatus(
            @PathVariable Long warningId,
            @RequestParam String status) {
        logger.info("更新学业预警状态，warningId: {}, status: {}", warningId, status);
        
        boolean result = academicWarningService.updateWarningStatus(warningId, status);
        Map<String, Object> response = new HashMap<>();
        response.put("success", result);
        
        if (!result) {
            response.put("message", "更新学业预警状态失败");
        }
        
        return response;
    }
    
    // 检查学生是否有未解决的学业预警
    @GetMapping("/users/{studentId}/has-warnings")
    public ResponseEntity<Map<String, Object>> hasUnresolvedWarnings(@PathVariable String studentId) {
        logger.info("检查学生是否有未解决的学业预警，studentId: {}", studentId);
        boolean hasWarnings = academicWarningService.hasUnresolvedWarnings(Long.valueOf(studentId));
        Map<String, Object> response = new HashMap<>();
        response.put("hasWarnings", hasWarnings);
        logger.info("学生 {} {} 未解决的学业预警", studentId, hasWarnings ? "有" : "没有");
        return ResponseEntity.ok(response);
    }

    // 强制生成学业预警（从不及格成绩生成，无视是否已有记录）
    @PostMapping("/admin/academic-warnings/force-generate")
    public ResponseEntity<Map<String, Object>> forceGenerateWarnings() {
        logger.info("开始从不及格成绩强制生成学业预警");
        try {
            // 获取所有不及格成绩
            List<Grade> failedGrades = gradeMapper.selectList(
                new QueryWrapper<Grade>()
                    .lt("final_grade", 60.0)
            );
            
            int count = 0;
            for (Grade grade : failedGrades) {
                try {
                    // 先删除该学生该课程的所有预警记录
                    academicWarningMapper.delete(
                        new QueryWrapper<AcademicWarning>()
                            .eq("student_id", grade.getStudentId())
                            .eq("course_id", grade.getCourseId())
                    );
                    
                    // 获取课程信息
                    Course course = courseMapper.selectById(grade.getCourseId());
                    if (course == null) {
                        continue;
                    }
                    
                    // 获取教师信息
                    User teacher = userMapper.selectById(course.getTeacherId());
                    String teacherName = teacher != null ? teacher.getRealName() : "未知";
                    
                    // 获取学生信息
                    User student = userMapper.selectById(grade.getStudentId());
                    String studentName = student != null ? student.getRealName() : "未知";
                    
                    // 创建学业预警
                    AcademicWarning warning = new AcademicWarning();
                    warning.setStudentId(Long.valueOf(grade.getStudentId()));
                    warning.setCourseId(grade.getCourseId());
                    warning.setCourseName(course.getName());
                    warning.setTeacherId(course.getTeacherId());
                    warning.setTeacherName(teacherName);
                    warning.setSemester(grade.getSemester());
                    warning.setCourseCredit(Double.valueOf(course.getCredits()));
                    warning.setWarningType("成绩不及格");
                    warning.setDescription(String.format(
                        "学生 %s 在课程 %s 中成绩不及格，最终成绩为 %.1f 分，低于及格线 60 分。",
                        studentName, course.getName(), grade.getFinalGrade()
                    ));
                    warning.setWarningDate(LocalDateTime.now());
                    warning.setStatus("ACTIVE");
                    warning.setCreateTime(LocalDateTime.now());
                    warning.setUpdateTime(LocalDateTime.now());
                    
                    int result = academicWarningMapper.insert(warning);
                    if (result > 0) {
                        count++;
                    }
                } catch (Exception e) {
                    logger.error("强制生成学业预警失败: {}", e.getMessage(), e);
                }
            }
            
            Map<String, Object> response = new HashMap<>();
            response.put("success", true);
            response.put("message", "强制生成学业预警成功，共生成 " + count + " 条记录");
            logger.info("强制学业预警生成成功，共生成 {} 条记录", count);
            return ResponseEntity.ok(response);
        } catch (Exception e) {
            logger.error("强制生成学业预警失败: {}", e.getMessage(), e);
            Map<String, Object> response = new HashMap<>();
            response.put("success", false);
            response.put("message", "强制生成学业预警失败: " + e.getMessage());
            return ResponseEntity.ok(response);
        }
    }
} 